package com.ftar.urgent.viewmodel;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.hardware.camera2.CameraDevice;
import android.util.Log;
import android.util.Size;
import android.view.View;
import android.widget.Toast;

import androidx.lifecycle.MutableLiveData;

import com.ftar.camera.listener.Camera2Listener;
import com.ftar.urgent.api.KnowledgeApi;
import com.ftar.urgent.api.req.KnowledageCommonReq;
import com.ftar.urgent.api.resp.CheckItemResp;
import com.ftar.urgent.api.resp.ItemRecordsVo;
import com.ftar.urgent.camera.Camera2Manager;
import com.ftar.urgent.constant.CameraConfig;
import com.ftar.urgent.databinding.ActivityCaptureBinding;
import com.ftar.urgent.http.FtHttpResponseHandler;
import com.ftar.urgent.http.HttpUtils;
import com.ftar.urgent.http.constant.ConstHttpUrl;
import com.ftar.urgent.http.model.CommonJson;
import com.ftar.urgent.http.model.PictureJsonBean;
import com.ftar.urgent.util.FileUtils;
import com.ftar.urgent.util.FtBitmapUtils;
import com.ftar.urgent.voice.OnLineAsrManager;
import com.rokid.utils.BitmapUtils;
import com.rokid.utils.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;

/**
 * @author: wei.jin
 * @date: 2023/6/5
 * @email: wei.jin@fanttec.com
 * @description：
 */
public class CaptureModel extends BaseModel {
    private String TAG = this.getClass().getSimpleName();
    private Context mContext;
    private ActivityCaptureBinding mBinding;
    private Camera2Manager mSysCameraManager;
    private final String mCaptureFile = "capture.jpg";
    private byte[] mPreviewData;

    public static final int STEP_IDLE = 1; //实景界面
    public static final int STEP_PICTURE = 2; //图片抓拍界面
    public static final int STEP_PICTURE_REG = 4; //图片实别有结果界面
    public static final int STEP_PICTURE_REG_FAILED = 5; //图片实别没有结果
    public static final int STEP_PICTURE_REG_VOICE = 6; //图片实别有结果,语音纠错界面
    public static final int STEP_SUCCESS = 7; //安信结果展示界面
    public static final int STEP_SUCCESS_MORE = 8; //安信结果更多展示界面
    public static final int STEP_SUCCESS_RESULT_EMPTY = 9; //安信结果识别结果为空
    public static final int STEP_VOICE_INDEX = 11; // 语音页面
    public static final int STEP_VOICE_REG = 12; // 语音识别有结果
    public static final int STEP_VOICE_REG_FAILED = 13; // 语音识别无结果

    public MutableLiveData<List<ItemRecordsVo>> anXinData = new MutableLiveData<>();
    public MutableLiveData<PictureJsonBean> pictureData = new MutableLiveData<>();

    public ItemRecordsVo resultViewData = new ItemRecordsVo();

    private int step = 1;
    private int currentPage = 1;
    private int totalSize = 0;
    private int totalPage = 1;
    private String currentPageStr;
    private String totalPageStr;
    private final String cachePath;

    public int getCurrentPage() {
        return currentPage;
    }

    public CaptureModel(Context context, ActivityCaptureBinding binding) {
        mContext = context;
        mBinding = binding;
        openCamera();
        //cachePath = mContext.getCacheDir().getPath();
        cachePath = "/sdcard";
    }

    public void openCamera() {
        mSysCameraManager = new Camera2Manager(mContext);
        mSysCameraManager.setOnCameraPreViewListener(new Camera2Listener() {
            @Override
            public void onCameraOpened(CameraDevice cameraDevice, String s, Size size, int i, boolean b) {

            }

            @Override
            public void onPreview(byte[] bytes, Camera camera) {
//                Log.d(TAG, "preview data");
                mPreviewData = bytes;
            }

            @Override
            public void onCameraClosed() {

            }

            @Override
            public void onCameraError(Exception e) {

            }

            @Override
            public void onCameraConfigurationChanged(int i, int i1) {

            }
        });
        mSysCameraManager.openCamera(mBinding.camera);
    }


    public int getStep() {
        return step;
    }

    /**
     * Set step update command
     *
     * @param step
     */
    public void setStep(int step) {
        this.step = step;
        Log.e(TAG, "---------------- step:" + step);
        mBinding.voiceLayout.setVisibility(View.GONE);
        mBinding.takePhotoLayout.setVisibility(View.GONE);
        mBinding.resultLayout.setVisibility(View.GONE);
        mBinding.resultMoreDetailView.setVisibility(View.GONE);
        mBinding.resultEmpty.setVisibility(View.GONE);
        mBinding.resultTitle.setVisibility(View.GONE);

        mBinding.commandTakePicture.setVisibility(View.GONE);
        mBinding.commandPictureSend.setVisibility(View.GONE);
        mBinding.commandReTakePicture.setVisibility(View.GONE);
        mBinding.commandBack.setVisibility(View.GONE);
        mBinding.commandMore.setVisibility(View.GONE);
        mBinding.commandCheckOver.setVisibility(View.GONE);
        mBinding.commandPreviousPage.setVisibility(View.GONE);
        mBinding.commandNextPage.setVisibility(View.GONE);
        mBinding.commandEnd.setVisibility(View.GONE);
        mBinding.commandAudio.setVisibility(View.GONE);

        switch (step) {
            case STEP_IDLE:
                mBinding.commandTakePicture.setVisibility(View.VISIBLE);
                mBinding.commandBack.setVisibility(View.VISIBLE);
                break;
            case STEP_PICTURE:
                //抓拍图片
                mBinding.takePhotoLayout.setVisibility(View.VISIBLE);
                mBinding.commandPictureSend.setVisibility(View.VISIBLE);
                mBinding.commandReTakePicture.setVisibility(View.VISIBLE);
                mBinding.commandBack.setVisibility(View.VISIBLE);
                break;
            //监测
            case STEP_PICTURE_REG:
                //抓拍图片 识别成功
                mBinding.takePhotoLayout.setVisibility(View.VISIBLE);
                mBinding.commandReTakePicture.setVisibility(View.VISIBLE);
                break;
            case STEP_PICTURE_REG_FAILED:
                mBinding.dialog.setVisibility(View.GONE);
                mBinding.resultTitle.setVisibility(View.VISIBLE);
                mBinding.takePhotoLayout.setVisibility(View.VISIBLE);
                mBinding.commandReTakePicture.setVisibility(View.VISIBLE);
                mBinding.commandBack.setVisibility(View.VISIBLE);
                break;
            case STEP_SUCCESS:
                mBinding.dialog.setVisibility(View.GONE);
                mBinding.resultLayout.setVisibility(View.VISIBLE);
                mBinding.resultTitle.setVisibility(View.VISIBLE);
                mBinding.resultTableLy.setVisibility(View.VISIBLE);
                mBinding.resultPageLy.setVisibility(View.VISIBLE);
                mBinding.commandMore.setVisibility(View.VISIBLE);
                mBinding.commandCheckOver.setVisibility(View.VISIBLE);
                mBinding.commandPreviousPage.setVisibility(View.VISIBLE);
                mBinding.commandNextPage.setVisibility(View.VISIBLE);
                break;
            case STEP_SUCCESS_MORE:
                mBinding.resultMoreDetailView.setVisibility(View.VISIBLE);
                mBinding.commandBack.setVisibility(View.VISIBLE);
                break;
            case STEP_SUCCESS_RESULT_EMPTY:
                mBinding.dialog.setVisibility(View.GONE);
                mBinding.resultTitle.setVisibility(View.VISIBLE);
                mBinding.resultEmpty.setVisibility(View.VISIBLE);
                mBinding.commandEnd.setVisibility(View.VISIBLE);
                break;
            case STEP_VOICE_INDEX:
                mBinding.voiceLayout.setVisibility(View.VISIBLE);
                mBinding.commandAudio.setVisibility(View.VISIBLE);
                mBinding.commandBack.setVisibility(View.VISIBLE);
                break;
            case STEP_VOICE_REG:
                mBinding.voiceLayout.setVisibility(View.VISIBLE);
                mBinding.commandPictureSend.setVisibility(View.VISIBLE);
                mBinding.commandBack.setVisibility(View.VISIBLE);
                mBinding.commandAudio.setVisibility(View.VISIBLE);
                break;
            case STEP_VOICE_REG_FAILED:
                mBinding.voiceLayout.setVisibility(View.VISIBLE);
                mBinding.commandBack.setVisibility(View.VISIBLE);
                mBinding.commandAudio.setVisibility(View.VISIBLE);
                break;
        }
    }


    public PictureJsonBean mapCustomSize(PictureJsonBean pictureJsonBean) {
        int width = mBinding.getRoot().getWidth();
        int height = mBinding.getRoot().getHeight();
        float ratioX = Float.valueOf((width * 100 / mBinding.photo.getWidth())) / 100;
        float ratioY = Float.valueOf((height * 100 / mBinding.photo.getHeight())) / 100;
        double x1 = (pictureJsonBean.getX1() * ratioX);
        double x2 = (pictureJsonBean.getX2() * ratioX);
        double y1 = (pictureJsonBean.getY1() * ratioY);
        double y2 = (pictureJsonBean.getY2() * ratioY);

        return new PictureJsonBean(x1, y1, x2, y2, pictureJsonBean.getScore(), pictureJsonBean.getType());
    }
    /**
     * Take photo
     *
     * @return
     */
    public void takePhoto() {
        setStep(CaptureModel.STEP_PICTURE);
        if (mPreviewData != null) {
            mBinding.takePhotoLayout.setVisibility(View.VISIBLE);
            Bitmap bitmap = BitmapUtils.nv21ToBitmap(mPreviewData, CameraConfig.CAMERA_IMAGE_WIDTH, CameraConfig.CAMERA_IMAGE_HEIGHT);
            mBinding.photo.setImageBitmap(bitmap);
        }
    }

    /**
     * Re take photo
     */
    public void reTakPhoto() {
        mBinding.takePhotoLayout.setVisibility(View.GONE);
    }

    /**
     * Send photo
     */
    public void sendPhoto() {
        Bitmap bitmap = FtBitmapUtils.loadBitmapFromView(mBinding.photo);
        sendPictureToUnicom(bitmap);
    }

    /**
     * Send photo to unicom, unicom will detect things and return rect aera
     */
    private void sendPictureToUnicom(Bitmap bitmap) {
        //测试用地址
        String path = cachePath;
        //String path = "/sdcard";
        FileUtils.saveBitmap(bitmap, path + "/" + mCaptureFile);
        File file = new File(path + "/" + mCaptureFile);

        if (file == null || !file.exists()) {
            showToast("文件不存在");
            return;
        }
        RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("imagefile", mCaptureFile, fileBody)
                .build();
        String token = HttpUtils.getUnicomToken();
        Log.d(TAG, "token:" + token);

        mBinding.dialog.setVisibility(View.VISIBLE);
        HttpUtils.post(ConstHttpUrl.UNICOM_PICTURE_DETECT, token, requestBody, new FtHttpResponseHandler(mContext, PictureJsonBean.class) {
            @Override
            public void onSuccess(CommonJson json) {
                super.onSuccess(json);
                if (json.getResult() != null) {
                    PictureJsonBean result = (PictureJsonBean) json.getResult();
                    //result.setType("红领巾");
                    pictureData.postValue(result);
                } else {
                    showToast("图片没有结果");
                }
            }

            @Override
            public Boolean onFailure(String errorMessage) {
                mBinding.dialog.setVisibility(View.GONE);
                showToast("查找错误");
                Log.e(TAG,errorMessage);
                pictureData.postValue(null);
                return super.onFailure(errorMessage);
            }
        });
    }

    /**
     * Send to an xin and
     */
    public void sendToAnXin(String word) {
        if(StringUtils.isNullOrEmpty(word)){
            return;
        }
        CaptureModel model = this;
        new Thread(new Runnable() {
            @Override
            public void run() {
                KnowledageCommonReq req = new KnowledageCommonReq();
                //req.setClassifyCode(100007);
                //req.setTypeCode(100071);
                //req.setWord("安全");
                req.setClassifyCode(mBinding.getHandler().parentCode);
                req.setTypeCode(mBinding.getHandler().currentCode);
                req.setWord(word);
                req.setSize(1000);
                try {
                    CheckItemResp checkItemResp = KnowledgeApi.queryVoice(req);
                    if (checkItemResp.getRecords() == null) {
                        checkItemResp.setRecords(new ArrayList<>());
                    }
                    totalSize = checkItemResp.getTotal();
                    // 每页一个
                    totalPage = totalSize;
                    model.setTotalPageStr();
                    model.setCurrentPageStr();
                    anXinData.postValue(checkItemResp.getRecords());
                    if (checkItemResp.getRecords().size() > 0) {
                        resultViewData = (checkItemResp.getRecords().get(getCurrentPage() - 1));
                    } else {
                        resultViewData = new ItemRecordsVo();
                    }
                    mBinding.setCaptureModel(model);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
    }


    private void showToast(String message) {
        Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
    }

    public void setCurrentPageStr() {
        this.currentPageStr = String.format("第%s页", this.currentPage);
    }

    public void setTotalPageStr() {
        this.totalPageStr = String.format("共%s页", this.totalPage);
    }

    public String getCurrentPageStr() {
        return currentPageStr;
    }

    public String getTotalPageStr() {
        return totalPageStr;
    }

    public void goPreviousPage() {
        if (this.currentPage == 1) {
            return;
        }
        this.currentPage--;
        setCurrentPageStr();
        resultViewData = (anXinData.getValue().get(currentPage - 1));
        this.mBinding.setCaptureModel(this);
    }

    public void goNextPage() {
        if (this.currentPage == this.totalPage) {
            return;
        }
        this.currentPage++;
        setCurrentPageStr();
        resultViewData = (anXinData.getValue().get(this.currentPage - 1));
        this.mBinding.setCaptureModel(this);
    }


    /**
     * Asr Online Start
     */
    public void startOnlineAsr() {
        mBinding.voiceRecorder.startRecording();

        List<String> group = new ArrayList<>();

        //Change word
        OnLineAsrManager.getInstance(cachePath).startAsr(group, new OnLineAsrManager.OnAsrResultListener() {
            @Override
            public void onResult(String result) {
                Log.d(TAG, "online:" + result);
                PictureJsonBean pictureJsonBeans = pictureData.getValue();
                if(pictureJsonBeans == null){
                    pictureJsonBeans = new PictureJsonBean(result);
                }
                pictureJsonBeans.setType(result);
                pictureData.postValue(pictureJsonBeans);
                stopOnLineAsr();

            }

            @Override
            public void onVolume(int volume) {
                mBinding.voiceRecorder.setVolume(volume);
            }
        }, mOnSocketStatusListener);
    }

    private OnLineAsrManager.OnSocketStatusListener mOnSocketStatusListener = new OnLineAsrManager.OnSocketStatusListener() {
        @Override
        public void onConnected() {
            ((Activity)mContext).runOnUiThread(new Runnable() {
                @Override
                public void run() {
//                    mBinding.commandOnlineAsr.setText(voice_record_stop);
                    mBinding.voiceLayout.setVisibility(View.VISIBLE);
                    showToast("语音打开成功");
                }
            });
        }

        @Override
        public void onLost() {
            ((Activity)mContext).runOnUiThread(new Runnable() {
                @Override
                public void run() {
//                    mBinding.commandOnlineAsr.setText(voice_record_start);
                    mBinding.voiceLayout.setVisibility(View.VISIBLE);
                    //showToast("在线语音连接失败");
                }
            });
        }
    };

    /**
     * Asr Online Stop
     */
    public void stopOnLineAsr() {
        mBinding.voiceRecorder.stopRecoding();
        OnLineAsrManager.getInstance(cachePath).stopRecognize();
    }
}
